
namespace Core
{
    using System.IO;
    using System.Linq;
    using System.Text;
    using Contracts.Interfaces;
    using System.Xml;
    using System;

    /// <summary>
    /// Xml fitting exporter class
    /// </summary>
    public sealed class XmlFittingExporter : IFittingExporter
    {
        /// <summary>
        /// Export a fitting instance to a xml string representation
        /// </summary>
        /// <param name="fitting">An instance of IFitting</param>
        /// <returns>A string representation of the IFitting instance or null</returns>
        public string Export(IFitting fitting)
        {
            if (fitting == null ) return null;

            var sb = new StringBuilder();
            Export(fitting, sb);
            return sb.ToString();
        }
        /// <summary>
        /// Export a fitting instance to a xml string representation
        /// </summary>
        /// <param name="fitting">An instance of IFitting</param>
        /// <param name="stringBuilder">A StrinBuilder instance to use</param>
        public void Export(IFitting fitting, StringBuilder stringBuilder)
        {
            if (fitting == null || stringBuilder ==null) return;

            stringBuilder.AppendFormat("<fitting name=\"{0}\"><robot name=\"{1}\">",
                fitting.Name,
                fitting.Robot.Name);

            foreach (var module in fitting.Robot.Modules.OrderBy(m => m.SlotGroup))
                stringBuilder.AppendFormat("<{0}>{1}{2}</{0}>",
                    module.SlotGroup.ToString().ToLower(),
                    module.Name,
                    module.Ammunitions != null ? ", " + module.Ammunitions.Name : null);

            stringBuilder.Append("</robot></fitting>");
        }

        /// <summary>
        /// Export a fitting instance to a stream
        /// </summary>
        /// <param name="fitting">An IFitting instance</param>
        /// <param name="stream">A stream</param>
        public void Export(IFitting fitting, Stream stream)
        {
            Export(fitting, stream, Encoding.UTF8);
        }

        /// <summary>
        /// Export a fitting instance to a stream
        /// </summary>
        /// <param name="fitting">An IFitting instance</param>
        /// <param name="stream">A stream</param>
        /// <param name="encoding">The Encoding to use</param>
        public void Export(IFitting fitting, Stream stream, Encoding encoding)
        {
            if (fitting == null)throw new ArgumentNullException("fitting");
            if (stream == null) throw new ArgumentNullException("stream");
            if (!stream.CanWrite)throw new IOException();
            
            using(var writer = XmlWriter.Create(stream, new XmlWriterSettings
                                                            {
                                                                CloseOutput = false, 
                                                                Encoding = encoding, 
                                                                CheckCharacters = true,
                                                                OmitXmlDeclaration = false
                                                            }))
            {

                writer.WriteStartElement("fitting");
                writer.WriteAttributeString("name", fitting.Name);
                writer.WriteStartElement("robot");
                writer.WriteAttributeString("name", fitting.Robot.Name);

                foreach (var module in fitting.Robot.Modules.OrderBy(m => m.SlotGroup))
                    writer.WriteElementString(
                        module.SlotGroup.ToString().ToLower(),
                        string.Format("{0}{1}", module.Name, module.Ammunitions != null ? ", " + module.Ammunitions.Name : null));

                writer.WriteEndElement();
             }
        }
    }
}